package controller

import (
	"blog_server/model"
	"blog_server/utils"
	"fmt"
	"github.com/gin-gonic/gin"
	"strconv"
	"strings"
)

func CreateArt(c *gin.Context) {
	var artReq model.ArticleRequest

	if err := c.ShouldBindJSON(&artReq); err != nil {
		fmt.Println(err)
		utils.Fail(c, nil)
		return
	}

	// 获取登录用户
	user, _ := c.Get("user")
	// 创建文章
	article := model.Article{
		UserId:     user.(model.User).ID,
		CategoryId: artReq.CategoryId,
		Title:      artReq.Title,
		Content:    artReq.Content,
		HeadImage:  artReq.HeadImage,
	}

	db := model.GetDB()
	err := db.Create(&article).Error

	if err != nil {
		fmt.Println(err)
		utils.Fail(c, nil)
		return
	}

	utils.Success(c, gin.H{"id": article.ID})
}

func UpdateArt(c *gin.Context) {
	var artReq model.ArticleRequest
	// 数据验证
	if err := c.ShouldBindJSON(&artReq); err != nil {
		utils.Fail(c, nil)
		return
	}
	// 获取path中的id
	articleId := c.Params.ByName("id")
	// 查找文章
	var article model.Article
	db := model.GetDB()
	if err := db.Where("id = ?", articleId).First(&article).Error; err != nil {
		utils.Fail(c, nil)
		return
	}
	// 获取登录用户
	user, _ := c.Get("user")
	userId := user.(model.User).ID
	if userId != article.UserId {
		utils.Fail(c, nil)
		return
	}
	// 更新文章
	if err := db.Model(&article).Updates(artReq).Error; err != nil {
		utils.Fail(c, nil)
		return
	}
	utils.Success(c, nil)
}

func DeleteArt(c *gin.Context) {
	// 获取path中的id
	articleId := c.Params.ByName("id")
	// 查找文章
	var article model.Article
	db := model.GetDB()
	if err := db.Where("id = ?", articleId).First(&article).Error; err != nil {
		utils.Fail(c, nil)
		return
	}
	// 获取登录用户
	user, _ := c.Get("user")
	userId := user.(model.User).ID
	if userId != article.UserId {
		utils.Fail(c, nil)
		return
	}
	// 删除文章
	if err := db.Delete(&article).Error; err != nil {
		utils.Fail(c, nil)
		return
	}
	utils.Success(c, nil)
}

func ShowArt(c *gin.Context) {
	// 获取path中的id
	articleId, _ := strconv.Atoi(c.Params.ByName("id"))

	// 查找文章
	var article model.Article
	db := model.GetDB()

	if err := db.Model(&model.Article{}).Where("id = ?", uint(articleId)).Find(&article).Error; err != nil {
		fmt.Println("err: find article err: ", err)
		utils.Fail(c, nil)
		return
	}

	if err := db.Model(&article).Update("read_cnt", article.ReadCnt+1).Error; err != nil {
		utils.Fail(c, nil)
		return
	}

	// 展示文章详情
	utils.Success(c, gin.H{"article": article})
}

func ShowArtList(c *gin.Context) {
	// 获取关键词、分类、分页参数
	keyword := c.DefaultQuery("keyword", "")
	categoryId := c.DefaultQuery("categoryId", "0")
	pageNum, _ := strconv.Atoi(c.DefaultQuery("pageNum", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "5"))
	var query []string
	var args []string
	// 若关键词存在
	if keyword != "" {
		query = append(query, "(title LIKE ? OR content LIKE ?)")
		args = append(args, "%"+keyword+"%")
		args = append(args, "%"+keyword+"%")
	}
	// 若分类存在
	if categoryId != "0" {
		query = append(query, "category_id = ?")
		args = append(args, categoryId)
	}
	// 拼接query
	var querystr string
	if len(query) > 0 {
		querystr = strings.Join(query, " AND ")
	}
	// 页面内容
	var articles []model.ArticleInfo
	// 文章总数
	var count int64
	db := model.GetDB()
	// 查询文章
	switch len(args) {
	case 0:
		db.Table("articles").
			Select("articles.id, articles.category_id, categories.category_name, articles.title, " +
				"articles.head_image, articles.read_cnt, articles.created_at, articles.updated_at").
			Joins("left join categories on articles.category_id = categories.id").
			Order("created_at desc").
			Offset((pageNum - 1) * pageSize).
			Limit(pageSize).
			Find(&articles)
		db.Model(&model.Article{}).Count(&count)
	case 1:
		db.Table("articles").
			Select("articles.id, articles.category_id, categories.category_name, articles.title, "+
				"articles.head_image, articles.read_cnt, articles.created_at, articles.updated_at").
			Joins("left join categories on articles.category_id = categories.id").
			Where(querystr, args[0]).Count(&count).
			Order("created_at desc").
			Offset((pageNum - 1) * pageSize).
			Limit(pageSize).
			Find(&articles)
		db.Model(&articles).Count(&count)
	case 2:
		db.Table("articles").
			Select("articles.id, articles.category_id, categories.category_name, articles.title, "+
				"articles.head_image, articles.read_cnt, articles.created_at, articles.updated_at").
			Joins("left join categories on articles.category_id = categories.id").
			Where(querystr, args[0], args[1]).
			Order("created_at desc").
			Offset((pageNum - 1) * pageSize).
			Limit(pageSize).
			Find(&articles)
		db.Model(&articles).Count(&count)
	case 3:
		db.Table("articles").
			Select("articles.id, articles.category_id, categories.category_name, articles.title, "+
				"articles.head_image, articles.read_cnt, articles.created_at, articles.updated_at").
			Joins("left join categories on articles.category_id = categories.id").
			Where(querystr, args[0], args[1], args[2]).
			Order("created_at desc").
			Offset((pageNum - 1) * pageSize).
			Limit(pageSize).
			Find(&articles)
		db.Model(&articles).Count(&count)
	}

	for index, article := range articles {
		var commentsCnt int64
		articleId := article.ID
		db.Model(&model.Comment{}).Where("article_id = ?", articleId).Count(&commentsCnt)
		//article.CommentCnt = uint(commentsCnt)
		fmt.Println(commentsCnt)
		articles[index].CommentCnt = uint(commentsCnt)
	}

	// 展示文章列表
	utils.Success(c, gin.H{"article": articles, "count": count})
}
